﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

// ReSharper disable CheckNamespace
namespace TroTro
// ReSharper restore CheckNamespace
{
    public class Sprite : DrawableGameComponent
    {
        #region Fields

        //private fields
        private float _scale = 1.0f;            //scale of the sprite
        private float _height;                  //height of the sprite
        private float _width;                   //width of the sprite
        private Rectangle _source;              //location of sprite-sheet

        //protected fields
        protected SpriteBatch SBatch;           //spritebatch for drawing


        //public fields
        public Color Tint = Color.White;        //the tint of the sprite; use alpha for transparency
        public Vector2 Origin = Vector2.Zero;   //origin is what it rotates around
        public Vector2 Position;                //position of the sprite
        public float Rotation;                  //the sprite's rotation

        #endregion

        #region Properties

        /// <summary>
        /// Height and Width are read only, so that they can't be changed outside the class.
        /// they are calculated from the Source rectangle's width and height and the scale factor
        /// </summary>
        public float Height
        {
            get { return _height; }
        }

        /// <summary>
        /// Height and Width are read only, so that they can't be changed outside the class.
        /// they are calculated from the Source rectangle's width and height and the scale factor
        /// </summary>
        public float Width
        {
            get { return _width; }
        }


        public float Scale
        {
            get { return _scale; }
            set
            {
                _scale = value;
                _height = _source.Height * _scale;
                _width = _source.Width * _scale;
            }
        }

        /// <summary>
        /// For reading from a sprite-sheet.
        /// </summary>
        public Rectangle Source
        {
            get { return _source; }
            set
            {
                _source = value;
                _height = _source.Height * _scale;
                _width = _source.Width * _scale;
            }
        }

        public Texture2D Texture
        {
            get;
            set;
        }

        public Vector2 Velocity
        {
            get;
            set;
        }

        #endregion

        #region XNA Methods

        public Sprite(Game game)
            : base(game)
        {
            SBatch = (SpriteBatch)game.Services.GetService(typeof(SpriteBatch));
        }

        protected override void LoadContent()
        {
            Source = new Rectangle(0, 0, Texture.Width, Texture.Height);
            Origin = new Vector2(Texture.Width, Texture.Height) * 0.5f;
            base.LoadContent();
        }

        /// <summary>
        /// Draws the sprite with the given spriteBatch.
        /// </summary>
        /// <param name="gametime"></param>
        public override void Draw(GameTime gametime)
        {
            SBatch.Draw(Texture, Position, Source, Tint, Rotation, Origin, Scale,
                SpriteEffects.None, 0);

            base.Draw(gametime);
        }

        #endregion

        #region Methods

        /// <summary>
        /// returns whether the two objects are colliding.
        /// </summary>
        /// <param name="other">The sprite to check collision against.</param>
        /// <returns>true if this sprite is colliding with other.</returns>
        internal bool CollidesWith(Sprite other)
        {
            return other != this && (Vector2.Distance(other.Position, this.Position) <
                ((other.Width + this.Width) / 2) ||
                Vector2.Distance(other.Position,
                    (this.Position + new Vector2(0, Game.GraphicsDevice.Viewport.Y))) <
                    ((other.Width + this.Width) / 2) ||
                    Vector2.Distance(other.Position, this.Position + new Vector2(0, -Game.GraphicsDevice.Viewport.Y)) < ((other.Width + this.Width) / 2) ||
                    Vector2.Distance(other.Position, this.Position + new Vector2(Game.GraphicsDevice.Viewport.X, 0)) < ((other.Width + this.Width) / 2) ||
                    Vector2.Distance(other.Position, this.Position + new Vector2(-Game.GraphicsDevice.Viewport.X, 0)) < ((other.Width + this.Width) / 2));
        }

        #endregion
    }
}
